package com.ymatou.iapi.settlement.testcase;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;

import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.settlement.parameter.SettleSellerIncomeAndChargeCommissionBean;
import com.ymatou.iapi.settlement.service.SettleSellerIncomeAndChargeCommissionCall;
import com.ymatou.iapi.settlement.service.SettlementService;
import com.ymatou.iapi.synctrade.service.TradingSyncService;
import com.ymt.base.YmatouEasyCall;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.AccountCallServiceV2;
import com.ymttest.business.service.PayGateWayCallService;
import com.ymttest.business.service.YMTTrading.TradingCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceAnliOrderCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceEngageOrderCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceOrderCallService;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.database.sqlwapper.DefaultWapper;
import com.ymttest.utils.DataUtil;

/**
 * 结算收入和扣佣接口 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_SettleSellerIncomeAndChargeCommission {
	private static SettleSellerIncomeAndChargeCommissionBean bean;
	private static SettleSellerIncomeAndChargeCommissionCall call;
	
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("结算收入和扣佣接口");
	}

	@Before
	public void caseUp() {
		bean = new SettleSellerIncomeAndChargeCommissionBean();
		call = new SettleSellerIncomeAndChargeCommissionCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(call.getOpurl());
		
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	@SuppressWarnings("rawtypes")
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleSellerIncomeAndChargeCommission_001() {
		Logger.start(true, "结算收入和扣佣成功");
		try {

			// 创建订单
			Logger.comment("前置数据准备");

			// 创建一个拼邮的订单
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithLogisticsType(LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();
			// 支付订单
			TradingCallService.payOrder(userId,
					placeOrderResp.getPayableAmount(),
					placeOrderResp.getTradingId());
			// 接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			TradingSyncService.getSyncResult(orderId);
			// 拼邮国际段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);
			TradingSyncService.getSyncResult(orderId);
			// 拼邮国内段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);
			TradingSyncService.getSyncResult(orderId);

			// 确认收货
			TradingCallService.confirmReceive(userId, orderId);

			Thread.sleep(3000);
			
			//调用结算接口
			TradingCallService.generateInvoicesOnOrderReceived(orderId, userId,
					placeOrderResp.getPayableAmount(), sellerId);

			Logger.comment("生成订单结算,扣拥结算单");

			Logger.comment("前置数据准备结束");
			// 结算前账户金额
			DefaultWapper defaultWapper = new DefaultWapper();

			BigDecimal price1 = AccountCallServiceV2.getAccountBalance(
					(int)sellerId, 1);

			bean.setOrderId(orderId);
			call.setData(bean);
			call.callService();

			Logger.verifyEquals("ok", call.getReturnData(), "验证返回报文");

			BigDecimal price2 = AccountCallServiceV2.getAccountBalance(
					(int)sellerId, 1);

			// 查询交易退款结算表
			List<Map> settlementInvoiceList = defaultWapper
					.selectYmtSettlementInvoice(orderId);

			Map settlemt1 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 1)
					.collect(Collectors.toList()).get(0);

			Map settlemt2 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 4)
					.collect(Collectors.toList()).get(0);

			Logger.verifyEquals(((BigDecimal) settlemt1.get("TotalAmount"))
					.subtract((BigDecimal) (BigDecimal) settlemt2
							.get("TotalAmount")), price2.subtract(price1).setScale(2),
					"验证商家账务余额变化");

			Logger.verifyEquals(1, (Integer) settlemt1.get("SettlementStatus"),
					"验证SettlementStatus");

			Logger.verifyEquals("确认收货订单结算", (String) settlemt1.get("Remark"),
					"验证Remark");

			Logger.verifyEquals(1, (Integer) settlemt1.get("SettlementStatus"),
					"验证SettlementStatus");

			Logger.verifyEquals("收取交易服务费结算", (String) settlemt2.get("Remark"),
					"验证Remark");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@SuppressWarnings("rawtypes")
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleSellerIncomeAndChargeCommission_002() {
		Logger.start(true, "重复结算");
		try {

			// 创建订单
			Logger.comment("前置数据准备");
			// 创建一个拼邮的订单
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithLogisticsType(LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			//支付
			Long thirdTradingId = TradingCallService.payOrder(userId,
					BigDecimal.ZERO, tradingId, "13");
			
			PayGateWayCallService.notifyCall("13",
					thirdTradingId.toString(),
					placeOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
					(int) userId);
			TradingSyncService.getSyncResult(orderId);
			// 接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			TradingSyncService.getSyncResult(orderId);
			// 拼邮国际段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);
			TradingSyncService.getSyncResult(orderId);
			// 拼邮国内段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);
			TradingSyncService.getSyncResult(orderId);

			// 确认收货
			TradingCallService.confirmReceive(userId, orderId);

			Thread.sleep(3000);

			Logger.comment("生成订单结算,扣拥结算单");
			
			//调用结算接口
			TradingCallService.generateInvoicesOnOrderReceived(orderId, userId,
					placeOrderResp.getPayableAmount(), sellerId);

			// 结算前账户金额
			DefaultWapper defaultWapper = new DefaultWapper();

			BigDecimal price1 = AccountCallServiceV2.getAccountBalance(
					(int)sellerId, 1);;

			bean.setOrderId(orderId);
			call.setData(bean);
			call.callService();
			Logger.comment("重复结算");
			call.callService();

			Logger.verifyEquals("ok", call.getReturnData(), "验证返回报文");

			BigDecimal price2 = AccountCallServiceV2.getAccountBalance(
					(int)sellerId, 1);

			// 查询交易退款结算表
			List<Map> settlementInvoiceList = defaultWapper
					.selectYmtSettlementInvoice(orderId);

			Map settlemt1 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 1)
					.collect(Collectors.toList()).get(0);

			Map settlemt2 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 4)
					.collect(Collectors.toList()).get(0);

			DataUtil.verifyDecimalEquals(((BigDecimal) settlemt1.get("TotalAmount"))
					.subtract((BigDecimal) (BigDecimal) settlemt2
							.get("TotalAmount")), price2.subtract(price1),
					"验证商家账务余额变化");

			Logger.verifyEquals(1, (Integer) settlemt1.get("SettlementStatus"),
					"验证SettlementStatus");

			Logger.verifyEquals("确认收货订单结算", (String) settlemt1.get("Remark"),
					"验证Remark");

			Logger.verifyEquals(1, (Integer) settlemt1.get("SettlementStatus"),
					"验证SettlementStatus");

			Logger.verifyEquals("收取交易服务费结算", (String) settlemt2.get("Remark"),
					"验证Remark");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleSellerIncomeAndChargeCommission_003() {
		Logger.start(false, "订单号为null");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			// bean.setOrderId(orderId);
			call.setData(bean);
			call.callService();

			Logger.verifyEquals("ok", call.getReturnData(), "验证返回报文");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@SuppressWarnings("rawtypes")
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleSellerIncomeAndChargeCommission_004() {
		Logger.start(true, "结算收入,扣佣金，返佣金，校验结算表，卖家资金流水表");
		try {

			// 创建订单
			Logger.comment("前置数据准备");
			// 创建一个拼邮的订单
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithLogisticsType(LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();
			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();
			long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			
			//支付
			Long thirdTradingId = TradingCallService.payOrder(userId,
					BigDecimal.ZERO, tradingId, "13");
			
			PayGateWayCallService.notifyCall("13",
					thirdTradingId.toString(),
					placeOrderResp.getPayableAmount().subtract(BigDecimal.ZERO).toString(),
					(int) userId);
			TradingSyncService.getSyncResult(orderId);
			
			// 接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			TradingSyncService.getSyncResult(orderId);
			// 拼邮国际段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);
			TradingSyncService.getSyncResult(orderId);
			// 拼邮国内段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);
			TradingSyncService.getSyncResult(orderId);

			// 确认收货
			TradingCallService.confirmReceive(userId, orderId);

			Thread.sleep(5000);

			Logger.comment("生成订单结算,扣拥结算单");
			
			//调用结算接口
			TradingCallService.generateInvoicesOnOrderReceived(orderId, userId,
					placeOrderResp.getPayableAmount(), sellerId);

			// 结算前账户金额
			DefaultWapper defaultWapper = new DefaultWapper();

			BigDecimal price1 = AccountCallServiceV2.getAccountBalance(
					(int)sellerId, 1);;

			bean.setOrderId(orderId);
			call.setData(bean);
			call.callService();
			Logger.verifyEquals("ok", call.getReturnData(), "验证返回报文");

			BigDecimal price2 = AccountCallServiceV2.getAccountBalance(
					(int)sellerId, 1);;

			// 查询交易退款结算表
			List<Map> settlementInvoiceList = defaultWapper
					.selectYmtSettlementInvoice(orderId);

			Map settlemt1 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 1)
					.collect(Collectors.toList()).get(0);

			Map settlemt2 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 4)
					.collect(Collectors.toList()).get(0);
			// 订单返佣
			Map settlemt3 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 6)
					.collect(Collectors.toList()).get(0);

			DataUtil.verifyDecimalEquals(((BigDecimal) settlemt1.get("TotalAmount"))
					.subtract((BigDecimal) (BigDecimal) settlemt2
							.get("TotalAmount")), price2.subtract(price1),
					"验证商家账务余额变化");

			Logger.verifyEquals(1, (Integer) settlemt1.get("SettlementStatus"),
					"验证SettlementStatus");

			Logger.verifyEquals("确认收货订单结算", (String) settlemt1.get("Remark"),
					"验证Remark");

			Logger.verifyEquals(1, (Integer) settlemt1.get("SettlementStatus"),
					"验证SettlementStatus");

			Logger.verifyEquals("收取交易服务费结算", (String) settlemt2.get("Remark"),
					"验证Remark");

			Logger.verifyEquals("返还交易服务费结算", (String) settlemt3.get("Remark"),
					"验证Remark");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@SuppressWarnings("rawtypes")
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleSellerIncomeAndChargeCommission_005() {
		Logger.start(true, "定金订单，买家违约导致订单取消，定金结算给买手，校验结算表");
		try {

			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp engagePlaceOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			
			Long userId = engagePlaceOrderResp.getUserId();
			long tradingId = engagePlaceOrderResp.getTradingId();
			long engageOrderId = engagePlaceOrderResp.getOrderList().get(0)
					.getOrderId();
			BigDecimal earnestAmount_1 = engagePlaceOrderResp.getOrderList().get(0).getOrderPayableAmount();

			// 支付定金
			TradingCallService.payOrder(userId,
					engagePlaceOrderResp.getPayableAmount(), tradingId, 2);
			TradingSyncService.getSyncResult(engageOrderId);
			
			// 二次确认下单
			TradingPlaceEngageOrderCallService.placeFullPaidOrder(userId, engageOrderId);
			TradingSyncService.getSyncResult(engageOrderId);
			
			// 修改paymentEndTime
			OrderShardingWapper orderShardingWapper = new OrderShardingWapper();

			OrderPo record = orderShardingWapper
					.selectOrderbyOrderId(engageOrderId);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.DAY_OF_MONTH, -10);

			record.setPaymentEndTime(calendar.getTime());

			// 修改paymentEndTime
			orderShardingWapper.orderMapper.updateByPrimaryKey(record);

			String orderJson = "{\"cancelReason\":\"自动化测试取消订单\",\"cancelType\":\"8\",\"orderId\":"
					+ engageOrderId + ",\"userId\":" + userId + "}";
			// 发送请求
			YmatouEasyCall autoCancelOrderCall = new YmatouEasyCall("", "POST",
					"JSON");
			autoCancelOrderCall
					.setUrl("http://optrade.iapi.ymatou.com/api/Buyer/bookingOrderUserViolationAutoCancel");
			autoCancelOrderCall.setData(orderJson);
			autoCancelOrderCall.callService();

			Logger.verifyEquals("ok", autoCancelOrderCall.getReturnData(),
					"验证ReturnData");
			
			Thread.sleep(10000);
			
			DefaultWapper defaultWapper = new DefaultWapper();

			// 查询交易退款结算表
			List<Map> settlementInvoiceList = defaultWapper
					.selectYmtSettlementInvoice(engageOrderId);

			// 预售订单买家违约，定金结算给买手。
			Map settlemt1 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 16)
					.collect(Collectors.toList()).get(0);

			Logger.verifyEquals(0, (Integer) settlemt1.get("SettlementStatus"),
					"验证SettlementStatus");

			Logger.verifyEquals("预售订单买家违约，定金结算给买手。", (String) settlemt1.get("Remark"),
					"验证Remark");

			Logger.verifyEquals(earnestAmount_1, (BigDecimal) settlemt1.get("TotalAmount"),
					"验证TotalAmount");

			Logger.verifyEquals(earnestAmount_1, (BigDecimal) settlemt1.get("CashAmount"),
					"验证CashAmount");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@SuppressWarnings("rawtypes")
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleSellerIncomeAndChargeCommission_006() {
		Logger.start(true, "安利会订单，扣除买手返点费用，校验结算表");
		try {

			// 创建订单
			Logger.comment("前置数据准备");

			long memberId = 2002;
			int memberOrderType = 0;

			TradingServiceResp placeOrder = TradingPlaceAnliOrderCallService
					.placeMultiProAnlihuiOrder(BigDecimal.TEN, false, memberId,
							memberOrderType);
			Long userId = placeOrder.getUserId();
			long sellerId = placeOrder.getOrderList().get(0).getSellerId();
			long orderId = placeOrder.getOrderList().get(0).getOrderId();
			long tradingId = placeOrder.getTradingId();
			BigDecimal totalPrice = placeOrder.getPayableAmount();

			Long thirdTradingId = TradingCallService.payOrder(userId,
					BigDecimal.ZERO, tradingId, "13");

			PayGateWayCallService.notifyCall("13", thirdTradingId.toString(),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue());
			TradingSyncService.getSyncResult(orderId);
			Thread.sleep(10000);
			
			SettlementService.generateAnliSettlement(orderId);

			// 接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);
			TradingSyncService.getSyncResult(orderId);

			// 拼邮国际段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 1);
			TradingSyncService.getSyncResult(orderId);

			// 拼邮国内段发货
			TradingCallService.delivery(sellerId, orderId,
					LogisticsTypeEnum.OVERSEAS_DELIVERY, 3);
			TradingSyncService.getSyncResult(orderId);

			// 确认收货
			TradingCallService.confirmReceive(userId, orderId);
			TradingSyncService.getSyncResult(orderId);

			Logger.comment("前置数据准备结束");
			
			//调用结算接口
			TradingCallService.generateInvoicesOnOrderReceived(orderId, userId,
					placeOrder.getPayableAmount(), sellerId);
			
			// 结算前账户金额
			DefaultWapper defaultWapper = new DefaultWapper();

			BigDecimal price1 = AccountCallServiceV2.getAccountBalance(
					(int) sellerId, 1);
			
			bean.setOrderId(orderId);
			call.setData(bean);
			call.callService();
			
			Thread.sleep(2000);
			
			// 结算后账户金额
			BigDecimal price2 = AccountCallServiceV2.getAccountBalance(
					(int) sellerId, 1);
			
			// 查询交易退款结算表
			List<Map> settlementInvoiceList = defaultWapper
					.selectYmtSettlementInvoice(orderId);

			Map settlemt_1 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 1)
					.collect(Collectors.toList()).get(0);

			Map settlemt_4 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 4)
					.collect(Collectors.toList()).get(0);
			
			Map settlemt_17 = settlementInvoiceList.stream()
					.filter(m -> (Integer) m.get("BusinessType") == 17)
					.collect(Collectors.toList()).get(0);

			Logger.verifyEquals(((BigDecimal) settlemt_1.get("TotalAmount"))
					.subtract((BigDecimal) settlemt_4
							.get("TotalAmount")).subtract((BigDecimal) settlemt_17.get("TotalAmount")), price2.subtract(price1)
					.setScale(2), "验证商家账务余额变化");
			Logger.verifyEquals(1, (Integer) settlemt_17.get("SettlementStatus"),
					"验证SettlementStatus");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
